package com.xbongbong.paas.help.team;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.xbongbong.formula.constant.Constant;
import com.xbongbong.paas.constant.PaasConstant;
import com.xbongbong.paas.domain.entity.PaasAppEntity;
import com.xbongbong.paas.domain.entity.PaasMenuEntity;
import com.xbongbong.paas.domain.entity.ext.PaasFormEntityExt;
import com.xbongbong.paas.enums.DelEnum;
import com.xbongbong.paas.enums.PaySheetTypeEnum;
import com.xbongbong.paas.enums.PaymentSheetTypeEnum;
import com.xbongbong.paas.help.CommonHelp;
import com.xbongbong.paas.model.PaasAppModel;
import com.xbongbong.paas.model.PaasFormModel;
import com.xbongbong.paas.model.PaasMenuModel;
import com.xbongbong.paas.toolbox.exception.XbbException;
import com.xbongbong.paas.toolbox.util.DateTimeUtil;
import com.xbongbong.pro.domain.entity.FormTeamSetEntity;
import com.xbongbong.pro.enums.DistributorMarkEnum;
import com.xbongbong.pro.enums.PackageTypeEnum;
import com.xbongbong.pro.enums.teammembers.enums.FormDefaultPatternEnum;
import com.xbongbong.pro.model.FormTeamSetModel;
import com.xbongbong.pro.team.TeamLinkPOJO;
import com.xbongbong.saas.constant.BasicConstant;
import com.xbongbong.saas.constant.ParameterConstant;
import com.xbongbong.saas.constant.StringConstant;
import com.xbongbong.saas.constant.teammembers.TeamMembersConstant;
import com.xbongbong.saas.enums.FormTeamSetEnum;
import com.xbongbong.saas.enums.XbbRefTypeEnum;
import org.apache.commons.collections4.CollectionUtils;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Set;
import java.util.stream.Collectors;
/**
 *
 * @author 魏荣杰
 *
 */
@Component
public class FormTeamSetHelp {

    @Resource
    private FormTeamSetModel formTeamSetModel;
    @Resource
    private CommonHelp commonHelp;
    @Resource
    private PaasAppModel paasAppModel;
    @Resource
    private PaasMenuModel paasMenuModel;
    @Resource
    private PaasFormModel paasFormModel;


    /**
     * Description: 获取当前表单数据设置
     * @param corpid
     * @param formId
     * @param saasMark
     * @param businessType
     * @param distributorMark
     * @return com.xbongbong.pro.domain.entity.FormTeamSetEntity
     * @throws
     * @author 魏荣杰
     * @date 2021/12/30 11:25
     * @since
     */
    public FormTeamSetEntity getFormTeamSet(String corpid, Long formId, Integer saasMark, Integer businessType, Integer distributorMark) throws XbbException {
        List<FormTeamSetEntity> formTeamSetList = getFormTeamSetList(corpid, Collections.singletonList(formId), saasMark, businessType, distributorMark);
        return formTeamSetList.get(Constant.ZERO);
    }

    /**
     *
     * @Description: 获取表单数据设置
     * @param corpid
     * @param formIdList
     * @param saasMark
     * @param businessType
     * @param distributorMark
     * @return: java.util.List<com.xbongbong.pro.domain.entity.FormTeamSetEntity>
     * @Author: shen.yang
     * @Date: 2022/3/7  9:47
    */
    public List<FormTeamSetEntity> getFormTeamSetList(String corpid, List<Long> formIdList, Integer saasMark, Integer businessType, Integer distributorMark) throws XbbException {
        Map<String, Object> param = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        param.put(ParameterConstant.CORPID, corpid);
        param.put("formIdIn", formIdList);
        List<Integer> paymentSheetTypeList = PaymentSheetTypeEnum.getAllBusinessType();
        List<Integer> paySheetTypeList = PaySheetTypeEnum.getAllBusinessType();
        if(paymentSheetTypeList.contains(businessType)){
            businessType = XbbRefTypeEnum.PAYMENT_SHEET.getCode();
        }else if(paySheetTypeList.contains(businessType)){
            businessType = XbbRefTypeEnum.PAY_SHEET.getCode();
        }
        param.put(ParameterConstant.BUSINESS_TYPE, businessType);
        param.put(StringConstant.SAAS_MARK, saasMark);
        param.put(StringConstant.DISTRIBUTOR_MARK, distributorMark);
        param.put(StringConstant.DEL, BasicConstant.ZERO);
        List<FormTeamSetEntity> formTeamSetEntities = formTeamSetModel.findEntities(param);
        List<FormTeamSetEntity> formTeamSetEntityList = new ArrayList<>();
        //高级版、旗舰版如果有自己设置，如果没有自己设置就走默认规则；标准版直接走默认规则
        Integer feeType = commonHelp.getCurrentCompanyPackage(corpid);
        boolean ultimateTag = Objects.equals(feeType, PackageTypeEnum.ULTIMATE.getType());
        Map<Long, FormTeamSetEntity> formTeamSetEntityMap = formTeamSetEntities.stream().collect(Collectors.toMap(FormTeamSetEntity::getFormId, v -> v, (v1, v2) -> v1));
        for (Long formId : formIdList) {
            if(Objects.isNull(formTeamSetEntityMap.get(formId))){
                //没有保存过设置的form走初始化
                FormTeamSetEntity formTeamSetEntity = new FormTeamSetEntity();
                JSONArray jsonArray = new JSONArray();
                formTeamSetEntity.setId(BasicConstant.ZERO_LONG);
                formTeamSetEntity.setCorpid(corpid);
                formTeamSetEntity.setFormId(formId);
                formTeamSetEntity.setAddTime(DateTimeUtil.getInt());
                formTeamSetEntity.setUpdateTime(DateTimeUtil.getInt());
                formTeamSetEntity.setDel(DelEnum.NORMAL.getDel());
                formTeamSetEntity.setSaasMark(saasMark);
                formTeamSetEntity.setBusinessType(businessType);
                formTeamSetEntity.setDistributorMark(distributorMark);
                formTeamSetEntity.setPublicSwitch(0);
                formTeamSetEntity.setLabelId(new JSONArray());
                if (Objects.equals(distributorMark, DistributorMarkEnum.OTHER.getCode())) {
                    XbbRefTypeEnum xbbRefTypeEnum = XbbRefTypeEnum.getByCode(businessType);
                    switch (xbbRefTypeEnum) {
                        // 这些类型的没有共享隔离设置以及关联列表设置
                        case CUSTOMER_COMMUNICATE:
                        case COMMUNICATE_PLAN:
                        case PRODUCT:
                        case INVOICE:
                        case PURCHASE_INVOICE:
                        case OTHER_INCOME:
                        case OTHER_EXPENSE:
                        case FUND_TRANSFER:
                        case CREDIT_TEMPORARY_LIMIT:
                        case CREDIT_FIXED_LIMIT:
                        case SUPPLIER_COMMUNICATE:
                        case ASSEMBLE:
                        case INVENTORY:
                        case TRANSFER:
                        case PURCHASE_INSTOCK:
                        case REFUND_INSTOCK:
                        case OTHER_INSTOCK:
                        case PRODUCTION_INSTOCK:
                        case RETURNED_MATERIEL_INSTOCK:
                        case CONTRACT_OUTSTOCK:
                        case RETURNED_PURCHASE_OUTSTOCK:
                        case OTHER_OUTSTOCK:
                        case PRODUCTION_MATERIEL_OUTSTOCK:
                        case WORK_ORDER_OUTSTOCK:
                        case WAREHOUSE:
                        case RECEIPT_ORDER:
                        case SERVICE_PROJECT:
                            // 没有关联列表设置就给个空数组
                            formTeamSetEntity.setLinkForm(new JSONArray());
                            break;
                        default:
                            List<Integer> linkList = FormTeamSetEnum.getBusLinkList(businessType, ultimateTag, true);
                            getLinkBusArray(corpid, linkList, businessType, saasMark, distributorMark, jsonArray);
                            Integer model = FormDefaultPatternEnum.getModelValueByBusinessType(businessType);
                            formTeamSetEntity.setModel(model);
                            //默认为空数组
                            formTeamSetEntity.setLinkForm(jsonArray);
                            break;
                    }
                } else if (Objects.equals(distributorMark, DistributorMarkEnum.DISTRIBUTOR.getCode())){
                    //经销商没有继承配置，只走默认初始化,跟套餐版本也无关
                    List<Integer> linkList = FormTeamSetEnum.getBusLinkList( XbbRefTypeEnum.transferBusinessType4Distributor(businessType,distributorMark), null, true);
                    getLinkBusArray(corpid, linkList, businessType, saasMark, distributorMark, jsonArray);
                    Integer model = FormDefaultPatternEnum.getModelValueByBusinessType(businessType);
                    formTeamSetEntity.setModel(model);
                    //默认为空数组
                    formTeamSetEntity.setLinkForm(jsonArray);
                }
                formTeamSetEntityList.add(formTeamSetEntity);
            }else{
                FormTeamSetEntity formTeamSetEntity = formTeamSetEntityMap.get(formId);
                if (Objects.equals(feeType, PackageTypeEnum.FREE.getType()) || Objects.equals(feeType, PackageTypeEnum.STANDARD.getType())) {
                    JSONArray jsonArray = new JSONArray();
                    //标准版以及免费版
                    List<Integer> linkList = FormTeamSetEnum.getBusLinkList(businessType, ultimateTag, false);
                    getLinkBusArray(corpid, linkList, businessType, saasMark, distributorMark, jsonArray);
                    formTeamSetEntity.setModel(FormDefaultPatternEnum.getModelValueByBusinessType(businessType));
                    formTeamSetEntity.setLinkForm(jsonArray);
                }else if (Objects.equals(feeType, PackageTypeEnum.ADVANCED.getType())) {
                    //高级版,存在从旗舰版切换到高级版的过程，所以这边需要判断是不是高级版该有的规则，如果不是的话不应该展示
                    List<Integer> linkList = FormTeamSetEnum.getBusLinkList(businessType, ultimateTag, false);
                    //数据库存的关联业务
                    JSONArray linkForm = formTeamSetEntity.getLinkForm();
                    JSONArray finalLinkForm = new JSONArray();
                    if (Objects.nonNull(linkForm) && linkForm.size() > BasicConstant.ZERO) {
                        for (int i = 0; i < linkForm.size(); i++) {
                            JSONObject linkFormJSONObject = linkForm.getJSONObject(i);
                            Integer businessTypeLinkForm = linkFormJSONObject.getInteger(TeamMembersConstant.LINK_BUSINESS_TYPE_KEY);
                            if (CollectionUtils.isNotEmpty(linkList) && linkList.contains(businessTypeLinkForm)) {
                                finalLinkForm.add(linkFormJSONObject);
                            }
                        }
                        formTeamSetEntity.setLinkForm(finalLinkForm);
                        formTeamSetEntity.setModel(FormDefaultPatternEnum.getModelValueByBusinessType(businessType));
                    }
                }
                formTeamSetEntityList.add(formTeamSetEntity);
            }
        }

        return formTeamSetEntityList;
    }

    /**
     * 获取关联业务封装
     *
     * @param linkList
     * @param businessType
     * @param saasMark
     * @param distributorMark
     * @return
     */
    private void getLinkBusArray(String corpid, List<Integer> linkList, Integer businessType, Integer saasMark, Integer distributorMark, JSONArray jsonArray) {
        if(CollectionUtils.isEmpty(linkList)){
            return;
        }
        Set<Integer> businessSet = getEnableFormSet(corpid, linkList);
        for (int i = 0; i < linkList.size(); i++) {
            Integer code = linkList.get(i);
            if(businessSet.contains(code)){
                jsonArray.add(getTeamLinkPojo(code,saasMark,distributorMark,i));
            }
        }
    }

    /**
     * 获取启用的表单
     *
     * @param corpid   公司id
     * @param businessTypes
     * @return
     */
    private Set<Integer> getEnableFormSet(String corpid, List<Integer> businessTypes) {
        //获取启用的app
        Map<String,Object> params = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        params.put(ParameterConstant.CORPID,corpid);
        params.put(ParameterConstant.ENABLE, Constant.ONE);
        List<PaasAppEntity> apps = paasAppModel.list(params);

        //获取启用的菜单
        params.put("appIdList",apps.stream().map(PaasAppEntity :: getId).collect(Collectors.toSet()));
        params.remove("columns");
        List<PaasMenuEntity> menus = paasMenuModel.findEntitys(params);

        //获取启用的表单
        params.put("appIdIn",apps.stream().map(PaasAppEntity :: getId).collect(Collectors.toSet()));
        params.put("menuIdIn",menus.stream().map(PaasMenuEntity :: getId).collect(Collectors.toSet()));
        params.put("businessTypeList", businessTypes);
        //params.put("distributorMark",Constant.ZERO);
        List<PaasFormEntityExt> forms = paasFormModel.findEntitys(params);
        Set<Integer> businessSet = forms.stream().map(PaasFormEntityExt::getBusinessType).collect(Collectors.toSet());
        return businessSet;
    }

    /**
     *
     * @Description: 获取菜单级的pojo，用于团队成员详情页和编辑页展示关联列表
     * @param code
     * @param saasMark
     * @param distributorMark
     * @param sort
     * @return: com.xbongbong.pro.form.pojo.TeamLinkPOJO
     * @Author: shen.yang
     * @Date: 2022/2/23  10:58
     */
    public TeamLinkPOJO getTeamLinkPojo(Integer code, Integer saasMark, Integer distributorMark, Integer sort){
        TeamLinkPOJO teamLinkPOJO = new TeamLinkPOJO();
        XbbRefTypeEnum linkXbbRefTypeEnum = XbbRefTypeEnum.getByCode(code);
        teamLinkPOJO.setName(linkXbbRefTypeEnum.getName());
        teamLinkPOJO.setLinkBusinessType(code);
        teamLinkPOJO.setLinkSaasMark(saasMark);
        teamLinkPOJO.setDistributorMark(distributorMark);
        teamLinkPOJO.setSort(sort);
        return teamLinkPOJO;
    }


}
